/*
 * Login class for the login and registration window of the program
 * Author: Daniel Henderson
 * TCSS 360 Spring 2013 
 * University of Washington
 */

package View;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import Model.Controller;
import Model.User;

public class Login extends JPanel{
	/**
	 *@author Daniel Henderson
	 * Login class, used to setup the login window and registration to
	 * the system, including all the login functionality of the program.
	 */
	private static final long serialVersionUID = 6316166873535398641L;

	//private JPanel login;
	private JButton btnLogin;	
	private JButton btnRegister;	
	private JButton btnRegisterNow;	
	private JButton btnAbout;
	private JTextField txtLogin;	
	private JPasswordField txtPassword;	
	private JLabel labelLogin;	
	private JLabel labelPassword;	
	private Controller controller;	
	private JTextField txtName;
	private JTextField txtLoginReg;
	private JTextField txtEmail;
	private JPasswordField txtPasswordReg;
	private JPasswordField txtPassword2;
	private JLabel lblNameError;
	private JLabel lblLoginError;
	private JLabel lblEmailError;
	private JLabel lblPasswordError; 
	private JLabel lblPassword2Error; 
    private Dimension windowSize;
    private JDialog dialog;
    private JFrame frame;
	
	/**
	 * Constructor for the login class
	 * @param Controller the main controller class for the program
	 */
	public Login(final Controller control) {
		controller = control;
		this.setLayout(new FlowLayout());
		setup();
	} //Login
	
	/**
	 * Primary method that will setup the GUI for the Login window
	 */
	private void setup() {
		this.setLayout(new FlowLayout());
		windowSize = new Dimension(400, 250);
		Dimension loginSize = new Dimension(200, 300);
		this.setPreferredSize(loginSize);
		
		labelLogin = new JLabel("Username: ");
		labelPassword = new JLabel("Password: ");
		
		setupBtns();
		txtLogin = new JTextField();
		txtPassword = new JPasswordField();
		
		txtLogin.setPreferredSize(new Dimension(200, 25));
		txtPassword.setPreferredSize(new Dimension(200, 25));
		
		//Add Components to 
		this.add(labelLogin);
		this.add(txtLogin);
		this.add(labelPassword);
		this.add(txtPassword);
		this.add(btnLogin);
		this.add(btnRegister);	
		this.add(btnAbout);
	}
	
	/**
	 * Helper method that sets up the various buttons and Listeners
	 * via inner classes for each button.
	 */
	private void setupBtns() {
		btnLogin = new JButton("Login");
		btnRegister = new JButton("Register");
	  	btnRegisterNow = new JButton("Register");
	  	btnAbout = new JButton("About");

	  	//Login button listener setup.
		btnLogin.addActionListener(new ActionListener() {
		      public void actionPerformed(final ActionEvent the_event) {
		    	  String login = txtLogin.getText();
		    	  String password = new String(txtPassword.getPassword());
		    	  
		    	  if (the_event.getSource() == btnLogin) {
		    		  if(!login.isEmpty() && !password.isEmpty()) { //If both not empty
		    			  if(!controller.setCurrentUser(login, password)) { //If NOT successful (returned false) popup error below
		    				  JOptionPane.showMessageDialog(null, "Unknown User and password. Please try again or register an account"); 
		    				  txtLogin.setText("");
		    				  txtPassword.setText("");
		    			  }
		    		  }
		    		  else {
		    			  JOptionPane.showMessageDialog(null, "Login and/or Password is empty. Please try again");
		    		  }
		    	  }
		        }
		      });
		
		//About button listener setup.
		btnAbout.addActionListener(new ActionListener() {
		      public void actionPerformed(final ActionEvent the_event) {
		    	  if (the_event.getSource() == btnAbout) {

		    				  JOptionPane.showMessageDialog(null, "Created by: 3 Squared Software Systems \n" +
		    						  							  "University of Washington Spring 2013 \n" +
		    						  							  "TCSS 360 - Group Project \n" +
		    						  							  "Team: Daniel Henderson, Ching-Ting Huang, Jonathan Forbes \n" +
		    						  							  "Contact Email: 3squaredsoftwaresystems@gmail.com \n" +
		    						  							  "Team Website: https://code.google.com/p/3-squared-software-systems/"); 
		    			  }
		    		  }
		      });
		
		//Register button listener setup (Register button on main login window)
		btnRegister.addActionListener(new ActionListener() {
		      public void actionPerformed(final ActionEvent the_event) {		    	  
		    	  //Create Labels for the TextFields and add to array
		  		  JLabel lblName = new JLabel("Full Name: ");
				  JLabel lblLogin = new JLabel("Username: ");
				  JLabel lblEmail = new JLabel("Email: ");
				  JLabel lblPassword = new JLabel("Password: ");
				  JLabel lblPassword2 = new JLabel("Confirm Password: ");				  
				  JLabel [] labels = {lblName, lblLogin, lblEmail, lblPassword, lblPassword2};
				  
				  //Create labels to display error while registering. Add to array, then format the color
		  		  lblNameError = new JLabel();
				  lblLoginError = new JLabel();
				  lblEmailError = new JLabel();
				  lblPasswordError = new JLabel(); 
				  lblPassword2Error = new JLabel(); 				  
				  JLabel [] errorLabels = {lblNameError, lblLoginError, lblEmailError, lblPasswordError, lblPassword2Error};
				  
				  lblNameError.setForeground(Color.red);
				  lblLoginError.setForeground(Color.red);
				  lblEmailError.setForeground(Color.red);
				  lblPasswordError.setForeground(Color.red);
				  lblPassword2Error.setForeground(Color.red);
				  
				  //Create TextFields for information entry on registration page, add to array
				  txtName = new JTextField(12);
				  txtLoginReg = new JTextField(12);
				  txtEmail = new JTextField(12);
				  txtPasswordReg = new JPasswordField(12);
				  txtPassword2 = new JPasswordField(12);
				  JTextField [] textFields = {txtName, txtLoginReg, txtEmail, txtPasswordReg, txtPassword2};
				  
				  //Set default size of textFields
				  Dimension textSize = new Dimension(100, 25);
				  txtName.setPreferredSize(textSize);
				  txtLoginReg.setPreferredSize(textSize);
				  txtEmail.setPreferredSize(textSize);
				  txtPasswordReg.setPreferredSize(textSize);
				  txtPassword2.setPreferredSize(textSize);
				  
				  //Add labels for Textfields
				  lblName.setLabelFor(txtName);
				  lblLogin.setLabelFor(txtLoginReg);
				  lblEmail.setLabelFor(txtEmail);
				  lblPassword.setLabelFor(txtPassword);
				  lblPassword2.setLabelFor(txtPassword2);
				  
				  //Create and format panel for Registration popup
		    	  JPanel panel = new JPanel();
		          GridBagLayout gridbag = new GridBagLayout();
		          GridBagConstraints c = new GridBagConstraints();
		          panel.setLayout(gridbag);
		          
		          //Set GridBag constraints
		          c.gridwidth = GridBagConstraints.REMAINDER; //last
		          c.anchor = GridBagConstraints.WEST;
		          c.weightx = 1.0;
		          panel.setBorder(
		                  BorderFactory.createCompoundBorder(
		                                  BorderFactory.createTitledBorder("Registration"),
		                                  BorderFactory.createEmptyBorder(5,5,5,5)));
		    	  frame = new JFrame();
		    	  dialog = new JDialog(frame, 
		    			  "Register",
		    			  true);
		    	  dialog.setContentPane(panel);
		    	  frame.setPreferredSize(windowSize);
		    	  dialog.setPreferredSize(windowSize);
		    	  dialog.setDefaultCloseOperation(
		    			  JDialog.DO_NOTHING_ON_CLOSE);
		    	  
		    	  frame.addWindowListener(new WindowAdapter() {
		    		  public void windowClosing(WindowEvent we) {
		    			  btnRegister.setEnabled(true);
		    			  btnLogin.setEnabled(true);
		    		  }
		    	  });
				
		    	  addLabelTextRows(labels, textFields, errorLabels, gridbag, panel);
		    	  lblNameError.setVisible(false);
		    	  lblLoginError.setVisible(false);
		    	  lblEmailError.setVisible(false);
		    	  lblPasswordError.setVisible(false);
		    	  lblPassword2Error.setVisible(false);
		    	  
		    	  if (the_event.getSource() == btnRegister) {
		    		  frame.add(panel);
		    		  frame.setVisible(true);
		    		  frame.setResizable(true);
		    		  frame.pack();
		    		  frame.setLocationRelativeTo(null);
		    		  btnRegister.setEnabled(false);
		    		  btnLogin.setEnabled(false);
		    	  }
		        }
		      });
		
		  //Register button listener setup (Register button inside the registration window)
	  	  btnRegisterNow.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent the_event) {	
		    	  lblNameError.setVisible(false);
		    	  lblLoginError.setVisible(false);
		    	  lblEmailError.setVisible(false);
		    	  lblPasswordError.setVisible(false);
		    	  lblPassword2Error.setVisible(false);
		    	  if (the_event.getSource() == btnRegisterNow) {//Check button source
		    		  if(!txtName.getText().isEmpty()) { //Name not Empty
		    			  if(!txtLoginReg.getText().isEmpty()) {//Login not Empty
		    				  if(!txtEmail.getText().isEmpty() && controller.emailContainsAt(txtEmail.getText())) {//Email not empty
		    					  if(txtPasswordReg.getPassword().length != 0) { // Password 1 not empty
			    					  if(txtPassword2.getPassword().length != 0 && controller.checkPasswordSame(new String(txtPasswordReg.getPassword()), new String(txtPassword2.getPassword()))) {//Password 2 not empty
			    						  if(controller.checkPasswordSizeCorrect(new String(txtPasswordReg.getPassword()))) {
				    						  if(controller.uniqueUsername(txtLoginReg.getText())) {//If user login is Unique (doesnt exist)
					    						  /* If we get here, there are no User Input errors
					    						   * on the registration page. Now let's try to create
					    						   * and add the new user with their information to the
					    						   * System.
					    						  */
				    							  User newUser = new User(txtLoginReg.getText(), 
				    									   new String(txtPasswordReg.getPassword()), 
				    									   txtEmail.getText(), 
				    									   txtName.getText());
				    							  if(!controller.addUserToSystem(newUser)) {//If user not added to system
						    						  lblPassword2Error.setText("Error - Registration failed. Please try again...");
						    				    	  lblPassword2Error.setVisible(true);
						    				    	  
						    				    	  //Remove old data in Text Boxes
						    						  txtName.setText("");
						    						  txtLoginReg.setText("");
						    						  txtEmail.setText("");
						    						  txtPasswordReg.setText("");
						    						  txtPassword2.setText("");
				    							  }
				    							  else {//Registration was Successful
				    								  JOptionPane.showMessageDialog(frame, "Registration Successful! Please login.");
				    								  frame.dispose();
				    								  frame.setVisible(false);
				    								  dialog.setVisible(false);
				    								  dialog.dispose();
				    								  clearLoginBox();
				    								  btnLogin.setEnabled(true);
				    								  btnRegister.setEnabled(true);
				    							  }
				    						  }
				    						  else {//User not UNIQUE
					    						  lblPassword2Error.setText("Error - Username already Exists.");
					    				    	  lblPassword2Error.setVisible(true);
				    						  }
			    						  }
			    						  else {//Password not correct length >= 8
				    						  lblPassword2Error.setText("Error - Password must be atleast 8 characters.");
				    				    	  lblPassword2Error.setVisible(true);
			    						  }
			    					  }
			    					  else {//Password Box 2 Empty
			    						  lblPassword2Error.setText("Error - Password Confirmation empty or not the same.");
			    				    	  lblPassword2Error.setVisible(true);
			    					  }
			    				  }
			    				  else {//Password Box 1 empty
		    						  lblPasswordError.setText("Error - Password Empty.");
		    				    	  lblPasswordError.setVisible(true);
			    				  }
		    				  }
		    				  else {//Email was empty
	    						  lblEmailError.setText("Error - Email Empty or does not contain \"@\" or \".\"");
	    				    	  lblEmailError.setVisible(true);
		    				  }
		    			  }
		    			  else {//Login was empty
		    				  lblLoginError.setText("Error - Username Empty.");
		    				  lblLoginError.setVisible(true);
		    			  }
		    		  }
		    		  else { //Name was empty
	    				  lblNameError.setText("Error - Name Empty.");
	    				  lblNameError.setVisible(true);
		    		  }
		    	  }
		        }
		      });
	}

	/**
	 * Helper method that clears the login textfields.
	 */
	public void clearLoginBox() {
		txtLogin.setText("");
		txtPassword.setText("");
	}
	
	/**
	 * Helper method that will format the registration window using the
	 * GridBag layout and constraints.
	 * @param JLabel[] contains the various labels for the reg window
	 * @param JTextField[] contains the various text fields for the reg window
	 * @param JLabel[] contains the various error labels
	 * @param GridBagLayout the layout used for the Reg window
	 * @param Container this is the panel for the Reg window
	 */
	private void addLabelTextRows(JLabel[] labels,
			JTextField[] textFields, JLabel[] errorLabels,
			GridBagLayout gridbag,
			Container container) {
		
		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.EAST;
		int numLabels = labels.length;

		for (int i = 0; i < numLabels; i++) {
			c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
			c.fill = GridBagConstraints.NONE;      //reset to default
			c.weightx = 0.0;                       //reset to default
			container.add(labels[i], c);

			c.gridwidth = GridBagConstraints.REMAINDER;     //end row
			c.fill = GridBagConstraints.HORIZONTAL;
			c.weightx = 1.0;
			container.add(textFields[i], c);
			container.add(errorLabels[i], c);
		}
		JPanel spaceBuff1 = new JPanel();
		c.gridwidth = GridBagConstraints.REMAINDER;     //end row
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 1.0;
		container.add(spaceBuff1, c);
		
		c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
		c.fill = GridBagConstraints.NONE;      //reset to default
		c.weightx = 0.0;                       //reset to default
		JPanel spaceBuff2 = new JPanel();


		container.add(spaceBuff2, c);
		container.add(btnRegisterNow, c);
	}
} 
